import re
import os
import sys
from datetime import datetime
import sqlite3
#coding=utf-8
'''
Sqlite部分，该部分主要是提取数据库中哪些TRANSID信息缺失，并输出相应的UDSN。
'''
cx = sqlite3.connect("sledb.db")
cu = cx.cursor()





#log_dict字典中的内容为日志中的重要信息项，键：日志中已有的英文信息或重要信息，键值是做了翻译或简化日志的信息。
log_dict={'iBoxLocationId = [49]':'iBoxLocationId = [49](Mei纸币回收箱)',
          'iBoxLocationId = [50]':'iBoxLocationId = [50](一元纸币找零箱)',
          'iBoxLocationId = [51]':'iBoxLocationId = [51](五元纸币找零箱)',
          'iBoxLocationId = [52]':'iBoxLocationId = [52](纸币废钞箱)',
          'iBoxRemainSum':'iBoxRemainSum(剩余金额)',
          'iBoxInitCount':'iBoxInitCount(初始化数量)',
          'iBoxInitSum':'iBoxInitSum(初始化金额)',
          'TRANSID':'TRANSID（交易ID）',
          'TransBeginTime':'TransBeginTime（交易起始时间）',
          'BizDate':'BizDate（交易审核时间）',
          'TransDate':'TransDate（交易时间）',
          'DeviceCode':'DeviceCode（设备ID）',
          '界面消息：乘客点击[ 取消 ]按键. [ 0 ]':'乘客点击[ 取消 ]按键. [ 0 ]',
          'Attention: 应付':'Attention(注意): 应付',
          'write card result':'write card result(写卡结果)',
          '[TRANS_CARD_INFO]':'[TRANS_CARD_INFO](一卡通交易表)',
          '[TRANS_YPT_INFO]':'[TRANS_YPT_INFO](一票通交易表)',
          '[TRANS_CHANGE_INFO]':'[TRANS_CHANGE_INFO](找零交易信息表)',
          '[TRANS_ENCASH_INFO]':'[TRANS_ENCASH_INFO](硬币交易信息表)',
          '[BOX_BILL_DETAIL_INFO]':'[BOX_BILL_DETAIL_INFO](纸币箱交易明细表)',
          '[TRANS_DATA_INFO]':'[TRANS_DATA_INFO](交易明细表)',
          'iBoxInstallStatus = [1]':'iBoxInstallStatus = [1]已安装',
          'iBoxInstallStatus = [0]':'iBoxInstallStatus = [0]未安装',
          'szBoxId':'szBoxId(箱ID)',
          'iBoxRemainCount':'iBoxRemainCount(剩余张数)',
          '找零失败':'找零失败',
          '应找零：':'应找零(单位:分):',
          '打印一票通故障单 完成':'打印一票通故障单完成',
          'Insert into DATA_BIZ_INFO,':'Insert into DATA_BIZ_INFO(XX表),',
          'Insert into DATA_BIZ_DEAL_INFO,':'Insert into DATA_BIZ_DEAL_INFO(XXX表),',
          '读取 充值卡 成功。':'读取充值卡成功,',
          '界面消息：乘客点击 [ 充值 ]按键.':'乘客点击 [ 充值 ]按键.',
          '写卡 充值金额为':'写卡充值金额为',
          '充值返回结果URL,返回结果[0]充值后金额':'充值后金额（分）'
          }
datalist=[]                  #所有提取的数据均存放在该列表中，每一个字典就是一笔交易。
datalist_count=0             #日志文件中的交易总数（包含有效交易、被取消的交易、日志残缺的交易）。
datadict={}                  #每一笔交易记录的各项信息存放在字典中。
Cancel_Trans_count=0         #取消交易计数器。
Cancel_TransID = []          #取消交易的TransID列表。
Trans_effect_count=0         #有效交易计数器。
Trans_full_count =0          #完整交易计数器。
Lack_TransID=[]              #不完整交易记录ID信息。
change_failure_count =0      #找零失败交易计数器。
change_Failure_List  =[]     #找零失败信息列表。
Rechargeable_card_count = 0  #充值交易计数器
'''
定义一个获取指定目录下所有tvmticket日志文件的函数，变量dirpath参数是绝对路径。
'''
def Get_Dir_File(dirpath):
    import glob
    import os
    file_lst = []
    filelist = glob.glob(dirpath + '**/tvmticket.*')
    for filename in filelist:
        #filename = os.path.basename(filename)
        file_lst.append(filename)
    return file_lst[::-1]

log_name_list = Get_Dir_File('C:/Python/untitled1') #指定当前目录为提取文件的目录。
'''
将指定目录下的日志文件根据先后顺序合并成一个文件。
'''
merge_file = open('mergelogfile.log','w',encoding='UTF-8')
for ln in Get_Dir_File('C:/Python/untitled1'):
    for log_txt in open(ln,'r',encoding='UTF-8'):   #ln这个变量还需要进行修改，因为他仅仅是遍历出来的名字，并不带路径。
        merge_file.write(log_txt)
merge_file.close()
'''
定义读取文件内容的函数，filename和dirpath参数(dirpath后必须加反斜杠)。
'''
def Get_file_text(filename, dirpath):
    with open(dirpath + filename, 'r', encoding = 'UTF-8') as f:
        file_text = f.readlines()
    return file_text

try:
    #for log_name in log_name_list:
        #log_file = Get_file_text(log_name,'C:/Python/untitled1/')
    log_file = open('mergelogfile.log', 'r', encoding='UTF-8')
except IOError:
    print('文件读取失败或文件不存在。')
'''
定义isset()函数来判断一个变量是否被定义。
'''
def isset(v):
   try :
       type (eval(v))
   except :
       return  0
   else :
       return  1

if os.path.exists( "newlogfile.log"):
#检测当前目录下是否存在newlogfile.log日志文件，如果存在则删除该文件。
    try:
        os.remove("newlogfile.log")
    except IOError:
        print('删除文件失败或属性为只读。')
for line in log_file:
    #提取每一行日志的日期信息
    dateRegex = re.compile(r'\d{4}-\d{2}-\d{2}')
    readdate = dateRegex.search(line)
    if readdate == None:
        continue
    else:
        log_date = readdate.group()
    # 提取每一行日志的时间信息
    timeRegex = re.compile(r'\d{2}:\d{2}:\d{2}.\d{3}')
    readtime = timeRegex.search(line)
    if readtime == None:
        continue
    else:
        log_time = readtime.group()
    #提取每一行日志[XXXX]后的内容信息
    testlog_Regex = re.compile(r'\[\d+\](.*$)')
    testlog_text = testlog_Regex.findall(line)
    if len(testlog_text) == 0:
        continue
    else:
        log_text = testlog_text[0]
        for v in log_dict.keys():
        #遍历字典中每一个key的值
            if v in log_text:
            #如果每一行的日志中包含key的内容
                log_text=log_text.replace(v,log_dict[v])
                #用字典中键值替换日志中key的内容
                if 'TRANSID' in log_text:
                    #提取交易id信息，并向列表中添加元素信息（字典）然后读取该元素下标（“datalist_sub”）
                    #提取列表当前元素下标的意义在于方便将其它元素内容添加到该下标的字典中
                    TRANSID_Regex = re.compile(r'\d+')
                    temp_TRANSID = TRANSID_Regex.findall(log_text)[0]
                    #print(temp_TRANSID)
                    datalist.append({'TRANSID':temp_TRANSID})
                    #print(datalist)
                    datalist_sub=datalist.index({'TRANSID':temp_TRANSID})
                    #print(datalist_sub)
                elif 'DeviceCode' in log_text:
                    #提取设备ID
                    if isset('datalist_sub'):
                        DeviceCode_Regex = re.compile(r'\d+.*')
                        temp_DeviceCode = DeviceCode_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('DeviceCode',temp_DeviceCode)
                        #print(datalist)
                elif 'BizDate' in log_text:
                    if isset('datalist_sub'):
                        BizDate_Regex = re.compile(r'\d{8}')
                        temp_BizDate = BizDate_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('BizDate',temp_BizDate)
                        #print(datalist)
                elif 'TransDate' in log_text:
                    #提取购票交易日期
                    if isset('datalist_sub'):
                        TransDate_Regex = re.compile(r'\d{8}')
                        temp_TransDate = TransDate_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('TransDate',temp_TransDate)
                        #print(datalist)
                elif 'TransBeginTime' in log_text:
                    #提取购票交易开始时间
                    if isset('datalist_sub'):
                        TransBeginTime_Regex = re.compile(r'\d{6}')
                        temp_TransBeginTime = TransBeginTime_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('TransBeginTime',temp_TransBeginTime)
                        #print(datalist)
                elif '乘客点击[ 取消 ]按键. [ 0 ]' in log_text:
                    #提取乘客是否取消交易操作
                    if isset('datalist_sub'):
                        datalist[datalist_sub].setdefault('Cancel_Trans','乘客取消此次操作')
                elif 'Attention(注意): 应付' in log_text:
                    #提取乘客购票的交易信息
                    if isset('datalist_sub'):
                        Tinfo_Regex = re.compile(r':\s(.*$)')
                        temp_Tinfo = Tinfo_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('Tinfo',temp_Tinfo)
                        #print(datalist)
                elif 'write card result(写卡结果)' in log_text:
                    # 提取乘客购票的物理卡号信息
                    if isset('datalist_sub'):
                        Card_Physics_Id_Regex = re.compile(r'[0-9a-fA-F]{20}')
                        temp_Card_Physics_Id = Card_Physics_Id_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('Card_Physics_Id',temp_Card_Physics_Id)
                        #print(datalist)
                elif '[TRANS_YPT_INFO](一票通交易表)' in log_text:
                    # 提取对一票通交易表的操作信息
                    if isset('datalist_sub'):
                        TRANS_YPT_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                        temp_TRANS_YPT_INFO_Verification = TRANS_YPT_INFO_Verification_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('TRANS_YPT_INFO_Verification',
                                                      temp_TRANS_YPT_INFO_Verification)
                        #print(datalist)
                elif '[TRANS_CARD_INFO](一卡通交易表)' in log_text:
                    # 提取对一卡通交易表信息的操作信息
                    if isset('datalist_sub'):
                        TRANS_CARD_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                        temp_TRANS_CARD_INFO_Verification = TRANS_CARD_INFO_Verification_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('TRANS_CARD_INFO_Verification',
                                                      temp_TRANS_CARD_INFO_Verification)
                elif '[TRANS_CHANGE_INFO](找零交易信息表)' in log_text:
                    # 提取找零交易信息表的操作信息
                    if isset('datalist_sub'):
                        TRANS_CHANGE_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                        temp_TRANS_CHANGE_INFO_Verification = TRANS_CHANGE_INFO_Verification_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('TRANS_CHANGE_INFO_Verification',
                                                      temp_TRANS_CHANGE_INFO_Verification)
                        #print(datalist)
                elif '[TRANS_ENCASH_INFO](硬币交易信息表)' in log_text:
                    # 提取投币交易信息表的操作信息
                    if isset('datalist_sub'):
                        TRANS_ENCASH_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                        temp_TRANS_ENCASH_INFO_Verification = TRANS_ENCASH_INFO_Verification_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('TRANS_ENCASH_INFO_Verification',
                                                          temp_TRANS_ENCASH_INFO_Verification)
                    #print(datalist)
                elif 'update [BOX_BILL_DETAIL_INFO]' in log_text:
                    # 提取纸币箱交易明细表的操作信息
                    #print(log_text)
                    if isset('datalist_sub'):
                        BOX_BILL_DETAIL_INFO_Verification_Regex = re.compile(r'szSQL = \[(.*)\]$')
                        temp_BOX_BILL_DETAIL_INFO_Verification = BOX_BILL_DETAIL_INFO_Verification_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('BOX_BILL_DETAIL_INFO_Verification',
                                                      temp_BOX_BILL_DETAIL_INFO_Verification)
                        #print(datalist)
                elif '[TRANS_DATA_INFO](交易明细表)' in log_text:
                    # 提取交易明细表的操作信息
                    if isset('datalist_sub'):
                        #print(log_text)
                        TRANS_DATA_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                        temp_TRANS_DATA_INFO_Verification = TRANS_DATA_INFO_Verification_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('TRANS_DATA_INFO_Verification',
                                                          temp_TRANS_DATA_INFO_Verification)
                elif '找零失败' in log_text:
                    # 筛选找零失败的交易信息，并提取找零失败code
                    if isset('datalist_sub'):
                        #print(log_text)
                        change_failure_Code_Regex = re.compile(r'\d+')
                        temp_change_failure_Code = change_failure_Code_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('change_failure_Code',
                                                          temp_change_failure_Code)
                        datalist[datalist_sub].setdefault('change_failure',
                                                          '找零失败')
                        change_failure_count+=1     #找零失败次数计数器
                        #print(datalist[datalist_sub])
                elif '应找零(单位:分):' in log_text:
                    # 筛选应找零金额信息
                    if isset('datalist_sub'):
                        #print(log_text)
                        if 'Should_change' in datalist[datalist_sub].keys():
                            pass
                        else:
                            Should_change_Regex = re.compile(r'\d+')
                            temp_Should_change = Should_change_Regex.findall(log_text)[0]
                            datalist[datalist_sub].setdefault('Should_change',temp_Should_change)
                        #print(datalist[datalist_sub])
                elif '打印一票通故障单完成' in log_text:
                    # 筛选打印故障单完成信息，来确认故障单是否正常打印成功。
                    if isset('datalist_sub'):
                        #print(log_text)
                        datalist[datalist_sub].setdefault('Fault_list','打印一票通故障单完成')
                        #print(datalist[datalist_sub])
                elif 'Insert into DATA_BIZ_INFO(XX表),' in log_text:
                    # 提取DATA_BIZ_INFO表的操作信息
                    if isset('datalist_sub'):
                        DATA_BIZ_INFO_Verification_Regex = re.compile(r'values\((.*)\);\]$')
                        temp_DATA_BIZ_INFO_Verification = DATA_BIZ_INFO_Verification_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('DATA_BIZ_INFO_Verification',
                                                          temp_DATA_BIZ_INFO_Verification)
                        #print(datalist[datalist_sub])
                elif 'Insert into DATA_BIZ_DEAL_INFO(XXX表),' in log_text:
                    # 提取DATA_BIZ_DEAL_INFO表的操作信息
                    if isset('datalist_sub'):
                        DATA_BIZ_DEAL_INFO_Verification_Regex = re.compile(r'values\((.*)\)\]$')
                        temp_DATA_BIZ_DEAL_INFO_Verification = DATA_BIZ_DEAL_INFO_Verification_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('DATA_BIZ_DEAL_INFO_Verification',
                                                          temp_DATA_BIZ_DEAL_INFO_Verification)
                        #print(datalist[datalist_sub])
                elif '读取充值卡成功,' in log_text:
                    # 提取充值前卡内余额信息
                    if isset('datalist_sub'):
                        Before_Rechargeable_card_balance_Regex = re.compile(r'(\d+).*')
                        temp_Before_Rechargeable_card_balance = Before_Rechargeable_card_balance_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('Before_Rechargeable_card_balance',
                                                          temp_Before_Rechargeable_card_balance)
                elif '写卡充值金额为' in log_text:
                    # 提取充值金额信息
                    if isset('datalist_sub'):
                        Rechargeable_card_money_Regex = re.compile(r'(\d+).*')
                        temp_Rechargeable_card_money = Rechargeable_card_money_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('Rechargeable_card_money',
                                                          temp_Rechargeable_card_money)
                elif '乘客点击[充值]按键.' in log_text:
                    # 提取乘客取消充值交易的操作信息
                    if isset('datalist_sub'):
                        datalist[datalist_sub].setdefault('Cancel_Rechargeable', '乘客取消充值')
                elif '充值后金额（分）' in log_text:
                    # 提取充值后卡内金额信息
                    if isset('datalist_sub'):
                        After_Rechargeable_card_money_Regex = re.compile(r'(\d+).*')
                        temp_After_Rechargeable_card_money = After_Rechargeable_card_money_Regex.findall(log_text)[0]
                        datalist[datalist_sub].setdefault('After_Rechargeable_card_money',
                                                          temp_After_Rechargeable_card_money)

    #print('日期：' + str(log_date) + ' 时间：' + str(log_time) + ' 日志：' + str(log_text))
    newlogfile = open('newlogfile.log', 'a', encoding='UTF-8')
    newlogfile.write('日期：' + str(log_date) + ' 时间：' + str(log_time) + ' 日志信息：' + str(log_text) + "\n")
    newlogfile.close
    #关闭新生成的日志文件。
#log_file.close()
#关闭源日志文件。
if os.path.exists( "newdict.log"):
#检测当前目录下是否存在newdict.log日志文件，如果存在则删除。
    try:
        os.remove("newdict.log")
    except IOError:
        print('文件不存在或属性为只读。')
datalist_count = len(datalist)
for x in range(0,datalist_count):
    newdict = open('newdict.log', 'a', encoding='UTF-8')
    newdict.write(str(datalist[x]) + "\n")
    newdict.close
    if ((('TRANS_CARD_INFO_Verification' in datalist[x].keys()) or ('TRANS_YPT_INFO_Verification' in datalist[x].keys())) \
        and ('TRANS_DATA_INFO_Verification' in datalist[x].keys()))\
        and (('TRANS_ENCASH_INFO_Verification' in datalist[x].keys()) \
        or ('BOX_BILL_DETAIL_INFO_Verification' in datalist[x].keys())):
        Trans_full_count+=1    #如果上面的条件都符合那么就说明这个交易是完整的，也许在这个地方是存在疏漏的
    else:
        # 交易日志残缺的交易中包含被取消的交易，所以需要进行一次筛选。
        if 'Cancel_Trans' in datalist[x].keys():
            #筛选出被取消交易的TRANSID信息
            Cancel_Trans_count += 1    #被取消交易计数器开始工作
            Cancel_TransID.append(datalist[x].get('TRANSID', 0))  #将当前TRANSID添加到Cancel_TransID列表中
            #print('以下是被取消交易的TRANSID：' + datalist[x].get('TRANSID', 0))
        else:
            #print(Lack_TransID.append(datalist[x].get('TRANSID',0)))
            Lack_TransID.append(datalist[x].get('TRANSID', 0))
    if '找零失败' in datalist[x].values():
        screen_key = ['TRANSID','TransBeginTime','Fault_list','Tinfo','Should_change']
        #找零失败相关信息在字典中的key，作为元素保存在screen_key列表中。
        screen_key_sum = len(screen_key)
        #提取screen_key的元素个数。
        for z in range(screen_key_sum):
            #print(datalist[x].get(screen_key[z],0))
            change_Failure_List.append(datalist[x].get(screen_key[z],0))
            #change_Failure_List作为找零失败相关信息存储的信息列表
        #print(change_Failure_List)
    else:
        pass
    if 'Rechargeable_card_money' in datalist[x].keys():
        #确定交易文件中有多少笔充值交易，以已有充值金额的交易确定该笔交易为充值交易。
        Rechargeable_card_count+=1       #充值计数器开始工作。
    else:
        pass

Trans_effect_count = datalist_count-Cancel_Trans_count
#有效交易总数（Trans_effect_count）=日志交易总数-被取消交易数
print('日志文件中交易总数共计：' + str(datalist_count) + '笔' )
print('有效交易共计：' + str(Trans_effect_count) + '笔' )
print('充值交易共计：' + str(Rechargeable_card_count) + '笔' )
print('被取消交易共计：'+ str(Cancel_Trans_count) + '笔')
print('被取消交易的TRANSID'+ str(Cancel_TransID))
print('日志交易完整的共计：' + str(Trans_full_count) + '笔' )
print('日志残缺的TRANSID:'+ str(Lack_TransID))
print('找零失败的交易共计:'+ str(change_failure_count) + '次')

for Failure_List_Show in range(0,len(change_Failure_List),5):
    #Failure_List_Show只作为临时遍历找零失败信息列表的下标。
    print('#####################################################################################\n'
          '****找零失败相关信息:\n'
          '****找零失败TRANSID:' + str(change_Failure_List[Failure_List_Show]) + '\n'
          '****交易时间:' + str(datetime.strptime(change_Failure_List[Failure_List_Show+1], '%H%M%S').time()) + '\n'
          '****故障单:' + str(change_Failure_List[Failure_List_Show+2]) + '\n'
          '****乘客购票信息:' + str(change_Failure_List[Failure_List_Show+3]) + '\n'
          '****故障金额:' + str(change_Failure_List[Failure_List_Show+4]) + '\n'
          '#####################################################################################\n'
          )
#定义一个搜索查询函数
def Tinfo_Search_query(dictlogfile,Search_text):
    Search_text = str(Search_text)
    try:
        dict_log = open(dictlogfile, 'r', encoding='UTF-8')
        #通过双循环遍历出符合查询条件的行。
        for line in dict_log:
            line = eval(line) # 将字符串转换成表达式（日志中读取的逐行信息为）
            for k, v in line.items():
                if Search_text == v:
                    print(line)
    except Exception as e:
        print('error detail ----。%s。'%e)

Tinfo_Search_query('newdict.log',15792)
Tinfo_Search_query('newdict.log',15791)
Tinfo_Search_query('newdict.log',15795)
Tinfo_Search_query('newdict.log',15796)
Tinfo_Search_query('newdict.log',15797)